package org.shagin.jfin.data.model.domain;

import java.util.Collections;
import java.util.Currency;
import java.util.LinkedList;
import java.util.List;

import org.shagin.jfin.data.Money;
import org.shagin.jfin.data.model.Account;
import org.shagin.jfin.data.model.Budget;
import org.shagin.jfin.data.model.CostCenter;
import org.shagin.jfin.data.util.MoneyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class AccountDomain.
 */
public class AccountDomain extends BudgetDomain {

    private static final Logger log = LoggerFactory
            .getLogger(AccountDomain.class);

    private List<Account> accounts = new LinkedList<Account>();

    /**
     * Instantiates a new account domain.
     */
    public AccountDomain(Budget budget) {
        super(budget);
    }

    /**
     * Find by id.
     * 
     * @param id the id
     * @return the account
     */
    public Account findById(String id) {
        Account result = null;
        for (Account account : accounts) {
            if (account.getId().equalsIgnoreCase(id)) {
                result = account;
                break;
            }
        }
        return result;
    }

    /**
     * Creates the account.
     * 
     * @param accountId the account id
     * @param amount the amount
     * @param costCenter the cost center
     * @return the account
     */
    private Account createAccount(String accountId, Money amount,
            CostCenter costCenter) {
        Account a = new Account(accountId, costCenter, amount, budget);
        return a;
    }

    /**
     * Adds the.
     * 
     * @param accountId the account id
     * @param costCenter the cost center
     * @param amount the amount
     * @return the account
     */
    public Account add(String accountId, CostCenter costCenter, Money amount) {
        Account result = findById(accountId);
        log.debug("add Account : " + accountId + " - " + amount.getValue()
                + " to " + costCenter.getId());
        if (null == result)
            result = createAccount(accountId, amount, costCenter);
        budget.fireAccountAddedEvent(result);
        accounts.add(result);
        return result;

    }

    /**
     * Gets the all.
     * 
     * @return the all
     */
    public List<Account> getAll() {
        return Collections.unmodifiableList(accounts);
    }

    /**
     * Gets the amount.
     * 
     * @param currency the currency
     * @return the amount
     */
    public Money getAmount(Currency currency) {
        Money result = MoneyUtil.zero(currency);
        for (Account account : accounts) {
            result = MoneyUtil.add(result, account.getAmount(), currency);
        }
        return result;
    }

}
